﻿using Modules;
using Modules.Corp;
using Modules.Person;
using PmSoft;
using static Modules.Person.PersonConstants;

namespace ManagementApi.Models.Manage.ProjectGroupMember
{
    /// <summary>
    /// 用工实体
    /// </summary>
    public class UseEmployeeDto
    {
        /// <summary>
        /// 成员id
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        /// 人员Id
        /// </summary>
        public int PersonId { get; set; }

        /// <summary>
        /// 人员状态
        /// </summary>
        public 进出场状态 Status { get; set; }

        /// <summary>
        /// 人员状态
        /// </summary>
        public string StatusName { get; set; }

        /// <summary>
        /// 姓名
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 项目Id
        /// </summary>
        public int ProjectId { get; set; }

        /// <summary>
        /// 所在项目
        /// </summary>
        public string ProjectName { get; set; }

        /// <summary>
        /// 项目编号
        /// </summary>
        public string ProjectNum { get; set; }

        /// <summary>
        /// 企业Id
        /// </summary>
        public int CorpId { get; set; }

        /// <summary>
        /// 所在企业
        /// </summary>
        public string CorpName { get; set; }

        /// <summary>
        /// 所在班组
        /// </summary>
        public string GroupName { get; set; }

        /// <summary>
        /// 工种
        /// </summary>
        public string WorkTypeName { get; set; }

        public 管理岗位类型? PostCategory { get; set; }

        /// <summary>
        /// 管理岗位类别
        /// </summary>
        public string? PostCategoryName { get; set; }

        /// <summary>
        /// 联系电话
        ///</summary>
        public string Mobile { get; set; }

        /// <summary>
        /// 民族
        /// </summary>
        public string Nation { get; set; }

        /// <summary>
        /// 工资计算方式
        /// </summary>
        public string SalaryCalculationMethod { get; set; }

        /// <summary>
        /// 合同类型
        /// </summary>
        public string ContractType { get; set; }

        /// <summary>
        /// 合同签订日期
        /// </summary>
        public DateTime? SigningDate { get; set; }

        /// <summary>
        /// 工资支付日期
        ///</summary>
        public int? SalaryPaymentDate { get; set; }

        /// <summary>
        /// 进场日期
        /// </summary>
        public DateTime? StartDate { get; set; }

        /// <summary>
        /// 离场日期
        /// </summary>
        public DateTime? EndDate { get; set; }

        /// <summary>
        /// 性别
        /// </summary>
        public string Sex { get; set; }

        /// <summary>
        /// 身份证号
        /// </summary>
        public string CardNumber { get; set; }

        /// <summary>
        /// 家庭住址
        /// </summary>
        public string Address { get; set; }

        /// <summary>
        /// 是否是管理人员
        /// </summary>
        public bool IsManager { get; set; }

        /// <summary>
        /// 是否有工资卡
        /// </summary>
        public bool HasBankCard { get; set; }

        /// <summary>
        /// 是否签订劳动合同
        /// </summary>
        public bool HasContract { get; set; }
    }

    public static partial class ProjectGroupMemberManagerExceptions
    {
        public static IEnumerable<UseEmployeeDto> AsUseEmployeeDtos(this IEnumerable<Modules.Project.Entitys.ProjectGroupMember> entitys, IEnumerable<Modules.Corp.CorpInfo> corps, IEnumerable<Modules.Project.ProjectInfo> projects, IEnumerable<Modules.Project.Entitys.ProjectGroup> groups, IEnumerable<PersonInfo> persons, IEnumerable<PersonCorpContract> personCorpContracts)
        {
            List<UseEmployeeDto> dtos = new();
            foreach (var item in entitys)
            {
                UseEmployeeDto dto = item.AsUseEmployeeDto(corps, projects, groups, persons, personCorpContracts);

                dtos.Add(dto);
            }
            return dtos;
        }

        public static UseEmployeeDto AsUseEmployeeDto(this Modules.Project.Entitys.ProjectGroupMember entity, IEnumerable<Modules.Corp.CorpInfo> corps, IEnumerable<Modules.Project.ProjectInfo> projects, IEnumerable<Modules.Project.Entitys.ProjectGroup> groups, IEnumerable<PersonInfo> persons, IEnumerable<PersonCorpContract> personCorpContracts)
        {
            UseEmployeeDto dto = new()
            {
                Id = entity.Id,
                PersonId = entity.PersonId,
                Status = entity.Status,
                StatusName = entity.Status.GetDescription(),
                Name = persons.FirstOrDefault(a => a.PersonId == entity.PersonId)?.Name ?? string.Empty,
                Sex = persons.FirstOrDefault(a => a.PersonId == entity.PersonId)?.Gender == 1 ? "男" : "女",
                CardNumber = persons.FirstOrDefault(a => a.PersonId == entity.PersonId)?.CardNumber ?? string.Empty,
                ProjectName = projects.FirstOrDefault(a => a.ProjectId == entity.ProjectId)?.Name ?? string.Empty,
                ProjectNum = projects.FirstOrDefault(a => a.ProjectId == entity.ProjectId)?.PrjNum ?? string.Empty,
                Address = persons.FirstOrDefault(a => a.PersonId == entity.PersonId)?.Address ?? string.Empty,
                CorpName = corps.FirstOrDefault(a => a.CorpId == entity.CorpId)?.Name ?? string.Empty,
                GroupName = groups.FirstOrDefault(a => a.GroupId == entity.GroupId)?.Name ?? string.Empty,
                WorkTypeName = entity.Type?.GetDescription() ?? string.Empty,
                Mobile = persons.FirstOrDefault(a => a.PersonId == entity.PersonId)?.Mobile ?? string.Empty,
                Nation = persons.FirstOrDefault(a => a.PersonId == entity.PersonId)?.Nation ?? string.Empty,
                SalaryCalculationMethod = personCorpContracts.OrderByDescending(a => a.EndDate).FirstOrDefault(a => a.PersonId == entity.PersonId)?.SalaryCalculationMethod.GetDescription() ?? string.Empty,
                ContractType = personCorpContracts.OrderByDescending(a => a.EndDate).FirstOrDefault(a => a.PersonId == entity.PersonId)?.Type.GetDescription() ?? string.Empty,
                SigningDate = personCorpContracts.OrderByDescending(a => a.EndDate).FirstOrDefault(a => a.PersonId == entity.PersonId)?.SigningDate,
                SalaryPaymentDate = personCorpContracts.OrderByDescending(a => a.EndDate).FirstOrDefault(a => a.PersonId == entity.PersonId)?.SalaryPaymentDate,
                StartDate = entity.StartDate,
                EndDate = entity.EndDate,
                ProjectId = entity.ProjectId,
                CorpId = entity.CorpId,
                IsManager = entity.IsManager,
                PostCategoryName = entity.PostCategory?.GetDescription(),
            };
            if (entity.PostCategory.HasValue)
            {
                dto.WorkTypeName = entity.PostCategory.Value.GetDescription();
            }
            var personBankService = ServiceAccessor.GetService<PersonBankService>();
            PersonBank? personBank = personBankService.GetDefaultPersonBankByIdCard(persons.FirstOrDefault(a => a.PersonId == entity.PersonId)?.CardNumber ?? string.Empty);
            if (personBank == null)
                dto.HasBankCard = false;
            else dto.HasBankCard = true;

            var personCorpContractService = ServiceAccessor.GetService<PersonCorpContractService>();
            PersonCorpContract? personCorpContract = personCorpContractService.GetPersonCorpContractsByProjectIdAndCorpIdPersonId(entity.ProjectId, entity.CorpId, entity.PersonId);
            if (personCorpContract == null)
                dto.HasContract = false;
            else dto.HasContract = true;
            return dto;
        }

        public static UseEmployeeDto AsManagerEmployeeDto(this Modules.Project.Entitys.ProjectGroupMember entity, IEnumerable<Modules.Corp.CorpInfo> corps, IEnumerable<Modules.Project.ProjectInfo> projects, IEnumerable<PersonInfo> persons, IEnumerable<PersonCorpContract> personCorpContracts)
        {
            UseEmployeeDto dto = new()
            {
                Id = entity.Id,
                PersonId = entity.PersonId,
                Status = entity.Status,
                StatusName = entity.Status.GetDescription(),
                Name = persons.FirstOrDefault(a => a.PersonId == entity.PersonId)?.Name ?? string.Empty,
                Sex = persons.FirstOrDefault(a => a.PersonId == entity.PersonId)?.Gender == 1 ? "男" : "女",
                CardNumber = persons.FirstOrDefault(a => a.PersonId == entity.PersonId)?.CardNumber ?? string.Empty,
                ProjectName = projects.FirstOrDefault(a => a.ProjectId == entity.ProjectId)?.Name ?? string.Empty,
                Address = projects.FirstOrDefault(a => a.ProjectId == entity.ProjectId)?.Address ?? string.Empty,
                CorpName = corps.FirstOrDefault(a => a.CorpId == entity.CorpId)?.Name ?? string.Empty,
                PostCategory = entity.PostCategory,
                PostCategoryName = entity.PostCategory?.GetDescription() ?? string.Empty,
                Mobile = persons.FirstOrDefault(a => a.PersonId == entity.PersonId)?.Mobile ?? string.Empty,
                Nation = persons.FirstOrDefault(a => a.PersonId == entity.PersonId)?.Nation ?? string.Empty,
                SalaryCalculationMethod = personCorpContracts.OrderByDescending(a => a.EndDate).FirstOrDefault(a => a.PersonId == entity.PersonId && a.CorpId == entity.CorpId && a.ProjectId == entity.ProjectId)?.SalaryCalculationMethod.GetDescription() ?? string.Empty,
                ContractType = personCorpContracts.OrderByDescending(a => a.EndDate).FirstOrDefault(a => a.PersonId == entity.PersonId)?.Type.GetDescription() ?? string.Empty,
                SigningDate = personCorpContracts.OrderByDescending(a => a.EndDate).FirstOrDefault(a => a.PersonId == entity.PersonId)?.SigningDate,
                SalaryPaymentDate = personCorpContracts.OrderByDescending(a => a.EndDate).FirstOrDefault(a => a.PersonId == entity.PersonId)?.SalaryPaymentDate,
                StartDate = entity.StartDate,
                EndDate = entity.EndDate,
            };

            var personBankService = ServiceAccessor.GetService<PersonBankService>();
            PersonBank? personBank = personBankService.GetDefaultPersonBankByIdCard(persons.FirstOrDefault(a => a.PersonId == entity.PersonId)?.CardNumber ?? string.Empty);
            if (personBank == null)
                dto.HasBankCard = false;
            else dto.HasBankCard = true;

            var personCorpContractService = ServiceAccessor.GetService<PersonCorpContractService>();
            PersonCorpContract? personCorpContract = personCorpContractService.GetPersonCorpContractsByProjectIdAndCorpIdPersonId(entity.ProjectId, entity.CorpId, entity.PersonId);
            if (personCorpContract == null)
                dto.HasContract = false;
            else dto.HasContract = true;
            return dto;
        }
    }
}